﻿using System;
using System.Collections.Generic;
using System.Text;

namespace LinkedList
{
    public class LinkedListQueue<E> : Queue<E>
    {

        private class Node
        {
            public E e;
            public Node next;
            public Node(E e, Node next)
            {
                this.e = e;
                this.next = next;
            }
            public Node(E e) : this(e, null) { }
            public Node() : this(default, null) { }
            public override string ToString()
            {
                return e.ToString();
            }
        }

        private Node head, tail;
        private int size;

        public LinkedListQueue()
        {
            head = null;
            tail = null;
            size = 0;
        }


        public int getSize()
        {
            return size;
        }


        public bool isEmpty()
        {
            return size == 0;
        }


        public void enqueue(E e)
        {
            if (tail == null)
            {
                tail = new Node(e);
                head = tail;
            }
            else
            {
                tail.next = new Node(e);
                tail = tail.next;
            }
            size++;
        }


        public E dequeue()
        {
            if (isEmpty())
                throw new Exception("Cannot dequeue from an empty queue.");

            Node retNode = head;
            head = head.next;
            retNode.next = null;
            if (head == null)
                tail = null;
            size--;
            return retNode.e;
        }


        public E getFront()
        {
            if (isEmpty())
                throw new Exception("Queue is empty.");
            return head.e;
        }


        public override String ToString()
        {
            StringBuilder res = new StringBuilder();
            res.Append("Queue: front ");

            Node cur = head;
            while (cur != null)
            {
                res.Append(cur + "->");
                cur = cur.next;
            }
            res.Append("NULL tail");
            return res.ToString();
        }


    }
}